Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Verifiable Credential JWS signed using known JSON WEB Key. #102

Open
wants to merge 1 commit into
base: gh-pages
Choose a base branch
from

Conversation

kdimak
Copy link

@kdimak kdimak commented Dec 16, 2019

The signature on example-016-jwt.jwt, example-016-jwt-presentation.jsonld, example-016-jwt-presentation-no-iss.jsonld, example-016-jwt-presentation-no-jti.jsonld is fixed using the RSA key in the example config.

In the existent test cases, it's not known what key was used to prepare VC JWT in the test data (e.g. example-016-jwt.jwt). Those defined at config.json.example or config.json.example.jwt do not fit.

VC JWS is generated from

{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://www.w3.org/2018/credentials/examples/v1"
  ],
  "id": "http://example.edu/credentials/3732",
  "type": ["VerifiableCredential", "AlumniCredential"],
  "issuer": "did:example:abfe13f712120431c276e12ecab",
  "issuanceDate": "2018-11-06T08:42:04Z",
  "expirationDate": "2019-11-06T08:42:03Z",
  "credentialSubject": {
    "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
    "alumniOf": "Example University"
  }
}

using RSA key from https://github.com/w3c/vc-test-suite/blob/gh-pages/config.json.example:

{
  "kty": "RSA",
  "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
  "e": "AQAB",
  "d": "X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q",
  "p": "83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs",
  "q": "3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk",
  "dp": "G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0",
  "dq": "s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk",
  "qi": "GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU",
  "alg": "RS256",
  "kid": "did:example:0xab#verikey-1"
}

Closes #101

@msporny msporny requested review from awoie and David-Chadwick March 31, 2021 14:31
@msporny
Copy link
Member

msporny commented Mar 31, 2021

@awoie and @David-Chadwick, can you both check to see if this PR breaks your implementations?

@David-Chadwick
Copy link
Contributor

We are not encoding our JWT keys in this way. When we first did the conformance tests there was no signature checking and we have not performed the tests since then. But the way this key is encoded will not allow us to check our signatures.

@msporny
Copy link
Member

msporny commented Apr 16, 2021

@kdimak and @David-Chadwick -- the two of you (and possibly @awoie) will have to figure out the proper encoding format, then. We are not going to be able to merge this until you have consensus.

@awoie
Copy link

awoie commented Apr 27, 2021

@mirceanis what are your thoughts?

@awoie
Copy link

awoie commented Apr 28, 2021

In general, I'm fine with the PR. It won't have an effect on our implementation.

But I guess @OR13 has some thoughts on how to use kid in JWKs which correlate with keys in DID Docs.

Copy link

@awoie awoie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@OR13
Copy link

OR13 commented Apr 28, 2021

The use of the kid in the JWK looks correct.

The use of kid in the header should match IMO, but i guess we save that for VC Data Model 2.0

eyJhbGciOiJSUzI1NiIsImtpZCI6ImRpZDpleGFtcGxlOjB4YWIjdmVyaWtleS0xIiwidHlwIjoiSldUIn0.eyJleHAiOjE1NzMwMjk3MjMsImlhdCI6MTU0MTQ5MzcyNCwiaXNzIjoiZGlkOmV4YW1wbGU6YWJmZTEzZjcxMjEyMDQzMWMyNzZlMTJlY2FiIiwianRpIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzM3MzIiLCJuYmYiOjE1NDE0OTM3MjQsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSIsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjEiXSwiY3JlZGVudGlhbFNjaGVtYSI6W10sImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImFsdW1uaU9mIjoiRXhhbXBsZSBVbml2ZXJzaXR5IiwiaWQiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxYzI3NmUxMmVjMjEifSwiaXNzdWVyIjoiIiwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkFsdW1uaUNyZWRlbnRpYWwiXX19.IC4Bqm8HyRG5nZYgG02KiGQpxSxQpkWgZ0gcmZmQYWD3wZWJnLzc_hSFDEAzW59SMhqBTEkWPDLnCai21KqCyyW2N6qVmNUFWjifdGYdx4i5ute8LOSw2Qr20tnrsY03qwJtzrnSkg7vVVtj996iShA1EnCwDp13l_RoTDh3ZBRy3VX5uTF32h6rbSEMBsxpkJSl7ZglQnUJcwOjRlGwUGpavcgLASZ0uYu5pc2RX0woFgez23R0gZkrDGlgbTlgacaCDtoAz4kqTTLYOMOAWWJG5DRGtvYGjVJwJy5iOi2Uwg53hDUMS2crnj5IPa1ABQthkMviFlWKsyIY9NWLVA
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some JWT implementations don't like the trailing newline. Can that be removed from this file?

e.g.
See trailing newline (0xa) with hexdump:

$ hexdump -C test/vc-data-model-1.0/input/example-016-jwt.jwt | tail -2
00000430  59 39 4e 57 4c 56 41 0a                           |Y9NWLVA.|
00000438

Check file size:

$ wc -c test/vc-data-model-1.0/input/example-016-jwt.jwt
1080 test/vc-data-model-1.0/input/example-016-jwt.jwt

Truncate by one character:

$ truncate -s 1079 test/vc-data-model-1.0/input/example-016-jwt.jwt

See trailing newline is no longer present:

$ hexdump -C test/vc-data-model-1.0/input/example-016-jwt.jwt|tail -2
00000430  59 39 4e 57 4c 56 41                              |Y9NWLVA|
00000437

Other ways to do it: https://unix.stackexchange.com/questions/140727/how-can-i-delete-a-trailing-newline-in-bash

Now the JWT can be verified with this jose command (https://github.com/latchset/jose) (after saving the JWK to key.jwk):

$ jose jws ver -i test/vc-data-model-1.0/input/example-016-jwt.jwt -k key.jwk

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The VC issuer property is an empty string. Shouldn't it instead be omitted, or match the iss claim?

https://www.w3.org/TR/vc-data-model/#issuer:

The value of the issuer property MUST be either a URI or an object containing an id property.

https://www.w3.org/TR/vc-data-model/#jwt-encoding:

iss MUST represent the issuer property of a verifiable credential or the holder property of a verifiable presentation.

Copy link
Member

@clehner clehner Aug 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decoded JWT:

{
  "alg": "RS256",
  "kid": "did:example:0xab#verikey-1",
  "typ": "JWT"
}
{
  "exp": 1573029723,
  "iat": 1541493724,
  "iss": "did:example:abfe13f712120431c276e12ecab",
  "jti": "http://example.edu/credentials/3732",
  "nbf": 1541493724,
  "sub": "did:example:ebfeb1f712ebc6f1c276e12ec21",
  "vc": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1",
      "https://www.w3.org/2018/credentials/examples/v1"
    ],
    "credentialSchema": [],
    "credentialSubject": {
      "alumniOf": "Example University",
      "id": "did:example:ebfeb1f712ebc6f1c276e12ec21"
    },
    "issuer": "",
    "type": [
      "VerifiableCredential",
      "AlumniCredential"
    ]
  }
}

Previous decoded JWT:

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "did:example:abfe13f712120431c276e12ecab#keys-1"
}
{
  "sub": "did:example:ebfeb1f712ebc6f1c276e12ec21",
  "jti": "http://example.edu/credentials/3732",
  "iss": "did:example:abfe13f712120431c276e12ecab",
  "nbf": 1541493724,
  "exp": 1573029723,
  "nonce": "660!6345FSer",
  "vc": {
    "@context": [
      "https://w3.org/2018/credentials/v1",
      "https://example.com/examples/v1"
    ],
    "type": [
      "VerifiableCredential",
      "UniversityDegreeCredential"
    ],
    "credentialSubject": {
      "degree": {
        "type": "BachelorDegree",
        "name": "Bachelor of Science in Mechanical Engineering"
      }
    }
  }
}

Diff, after rearranging some properties for consistency:

@@ -1,29 +1,29 @@
 {
   "alg": "RS256",
   "typ": "JWT",
-  "kid": "did:example:abfe13f712120431c276e12ecab#keys-1"
+  "kid": "did:example:0xab#verikey-1",
 }
 {
   "sub": "did:example:ebfeb1f712ebc6f1c276e12ec21",
   "jti": "http://example.edu/credentials/3732",
   "iss": "did:example:abfe13f712120431c276e12ecab",
   "nbf": 1541493724,
+  "iat": 1541493724,
   "exp": 1573029723,
-  "nonce": "660!6345FSer",
   "vc": {
     "@context": [
-      "https://w3.org/2018/credentials/v1",
-      "https://example.com/examples/v1"
+      "https://www.w3.org/2018/credentials/v1",
+      "https://www.w3.org/2018/credentials/examples/v1"
     ],
     "type": [
       "VerifiableCredential",
-      "UniversityDegreeCredential"
+      "AlumniCredential"
     ],
+    "issuer": "",
+    "credentialSchema": [],
     "credentialSubject": {
-      "degree": {
-        "type": "BachelorDegree",
-        "name": "Bachelor of Science in Mechanical Engineering"
-      }
+      "alumniOf": "Example University",
+      "id": "did:example:ebfeb1f712ebc6f1c276e12ec21"
     }
   }
 }

The Expiration time (exp claim) 1573029723 (2019-11-06T08:42:03Z) is in the past. This may cause verification to fail. How about set it to some date in the far future, or omit the claim/property entirely?

AlumniCredential is not in the example context currently but may be added soon: w3c/vc-data-model#783. UniversityDegreeCredential is in the context.

"credentialSchema": [] doesn't cause a problem for @spruceid's implementation, but I wonder if it is useful/necessary.

The new key id did:example:0xab#verikey-1 doesn't directly match the issuer did:example:abfe13f712120431c276e12ecab. But this is okay if we assume that did:example:abfe13f712120431c276e12ecab has did:example:0xab as a controller.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Correct JWK for decoding JWTs tests
7 participants